package l2

import (
	"fmt"
	"strconv"
	"zstackgo/pkg/core/cloudbus"
	"zstackgo/pkg/core/db"
	"zstackgo/pkg/header"
	"zstackgo/pkg/header/core"
	hl2 "zstackgo/pkg/header/network/l2"
	"zstackgo/pkg/header/network/service"
	"zstackgo/pkg/resourceconfig"
	"zstackgo/spring"

	"github.com/meilihao/golib/v2/log"
	"github.com/meilihao/golib/v2/misc"
)

func init() {
	o := new(L2NoVlanL2NetworkFactory)
	spring.Register(o, "L2NoVlanL2NetworkFactory", []*spring.PluginExtension{
		{
			Interface: "header.Component",
		},
		{
			Interface: "header.network.l2.L2NetworkFactory",
		},
		{
			Interface: "network.l2.L2NetworkDefaultMtu",
		},
		{
			Interface: "header.network.l2.L2NetworkGetVniExtensionPoint",
		},
	})
}

var (
	_ hl2.L2NetworkFactory              = new(L2NoVlanNetworkFactory)
	_ header.Component                  = new(L2NoVlanNetworkFactory)
	_ L2NetworkDefaultMtu               = new(L2NoVlanNetworkFactory)
	_ hl2.L2NetworkGetVniExtensionPoint = new(L2NoVlanNetworkFactory)
	_ hl2.VSwitch                       = new(L2NoVlanNetworkFactory)
)

var (
	typNoVlanNETWORK = hl2.NewL2NetworkType(hl2.L2_NO_VLAN_NETWORK_TYPE, true)
)

type L2NoVlanNetworkFactory struct {
	dbf db.DatabaseFacade `autowire:"DatabaseFacadeImpl"`
	bus cloudbus.CloudBus `autowire:"CloudBusImpl3"`
	rcf resourceconfig.ResourceConfigFacade
}

func (f *L2NoVlanNetworkFactory) GetVSwitchTypes() []*hl2.VSwitchType {
	vSwitchTypes := []*hl2.VSwitchType{
		hl2.LinuxBridge,
		hl2.OvsDpdk,
	}

	return vSwitchTypes
}

func (f *L2NoVlanNetworkFactory) GetType() *hl2.L2NetworkType {
	return typNoVlanNETWORK
}

func (f *L2NoVlanNetworkFactory) CreateL2Network(vo *hl2.L2NetworkVO, msg *hl2.APICreateL2VlanNetworkMsg, completion core.ReturnValueCompletion[any]) {
	f.dbf.GetEntityManager().Create(vo)
	inv := hl2.L2NetworkInventoryValueOf(vo)
	log.Glog.Debug(fmt.Sprintf("successfully create L2VlanNetwork, %s", misc.MarshalAnyString(inv)))

	completion.Success(inv)
}

// todo: missing vlan
func (f *L2NoVlanNetworkFactory) GetL2Network(vo *hl2.L2NetworkVO) hl2.L2Network {
	return NewL2NoVlanNetwork(vo)
}

func (f *L2NoVlanNetworkFactory) Start() error {
	return nil
}

func (f *L2NoVlanNetworkFactory) Stop() error {
	return nil
}

func (f *L2NoVlanNetworkFactory) GetL2NetworkType() string {
	return hl2.L2_NO_VLAN_NETWORK_TYPE
}

func (f *L2NoVlanNetworkFactory) GetDefaultMtu(inv *hl2.L2NetworkInventory) int64 {
	tmp := f.rcf.GetResourceConfigValue(service.DHCP_MTU_NO_VLAN, inv.Uuid)
	n, _ := strconv.ParseInt(tmp, 10, 64)
	return n
}

func (f *L2NoVlanNetworkFactory) GetL2NetworkVni(l2NetworkUuid string, hostUuid string) int {
	return 0
}

func (f *L2NoVlanNetworkFactory) GetL2NetworkVniType() string {
	return typNoVlanNETWORK.String()
}
